home *** CD-ROM | disk | FTP | other *** search
- comment *
-
- Purpose: API for producing sounds through AdLib
-
- Author: Yousuf J. Khan
-
- *
- include adlib.inc ;include macros
-
- .model tiny
- .code
-
- public delay
- delay proc near
- comment *
-
- Purpose:
- Produces a variable length delay on an AdLib or SoundBlaster
- card, by reading the address port a number of times. Just the
- act of calling a procedure, and doing a CX loop should add
- delays of its own, so this is a very conservative procedure.
- There should be more than enough delay here.
-
- Entry:
- CX: # of loops to produce (six loops after writing to address
- port, or thirty-five loops after writing to data port).
-
- Exit:
- nothing.
-
- *
- push dx
- mov dx, 388h ;AdLib address port at PC port 388h
- call sbdelay ;call generalized delay procedure
- pop dx
- ret
- endp
-
- public sbdelay
- sbdelay proc near
- comment *
-
- Purpose:
- Same as the Delay procedure, except the port has to be set ahead
- of time. More generalized procedure.
-
- Entry:
- DX: status/address port i/o address
- CX: # of loops to produce (six loops after writing to address
- port, or thirty-five loops after writing to data port).
-
- Exit:
- nothing.
-
- *
- push ax
- delayloop:
- in al, dx ;read address port
- loop delayloop
- pop ax
- ret
- endp
-
- public adlibinit
- adlibinit proc near
- comment *
-
- Purpose:
- Initializes AdLib registers to zero
-
- Entry:
- nothing.
-
- Exit:
- nothing.
-
- *
- mov al, 1
- zeroing_loop:
- push ax
- mov dx, 388h
- out dx, al ;writing to address port
- addrdelay
- mov al, 0 ;zero the data register
- mov dx, 389h
- out dx, al
- datadelay
- pop ax
- inc al
- ; there are only 245 AdLib registers (from 01h-F5h)
- cmp al, 0F5h ;as long as AL is between
- jbe short zeroing_loop ; 01-F5h, continue looping
- ret
- endp
-
- public detect_adlib
- detect_adlib proc near
- comment *
-
- Purpose:
- To detect whether an AdLib-compatible is installed
-
- Entry:
- nothing.
-
- Exit:
- AX=0, if no AdLib
- AX=1, if AdLib present
-
- *
- push dx ;save DX before tests begin
- setadlib 4,60h ;reset both Adlib timers
- setadlib 4,80h ;enable Adlib interrupts
- mov dx, 388h ;Status/Addr port
- in al, dx ;gives state#1
- test al, 0E0h ;AND state#1 with E0h
- jne short noAdLib ;if 0 then goto next test
- ;start 2nd state test
- setadlib 2,0FFh ;writing FFh to Adlib timer#1
- setadlib 4,21h ;start timer#1
- mov cx, 145 ;145 iteration loop,
- call delay ; or approx. 80ms delay
- mov dx, 388h ;Status/Addr port
- in al, dx ;gives state#2
- and al, 0E0h ;AND state#2 with E0h
- cmp al, 0C0h ;is state#2 right? yes, AdLib here
- mov ax, 1 ;set return value of AX=1
- jmp short eop
- noAdLib:
- mov ax, 0 ;set return value of AX=0
- eop:
- pop dx ;restore DX
- ret
- endp
-
- public detect_sb
- detect_sb proc near
- comment *
-
- Purpose:
- To detect whether a SoundBlaster-compatible is installed
-
- Entry:
- DS:DI-> pointer to word memory location to record SoundBlaster
- base port address to
-
- Exit:
- AX=0, if no SoundBlaster
- AX=1, if SoundBlaster present
- DS:DI-> returns last possible SB port tested
-
- *
-
- comment *
-
- Start scanning for a SoundBlaster base port on every PC
- port from 210h to 260h, in increments of 10h.
-
- *
- .data
- sbflag db 0 ;indicates how many port tests passed
- sbport dw 210h ;i/o port where SB is located
- .code
- push dx ;save DX before tests begin
- mov dx, 210h ;first port to check
- mov [di], dx ;save to passed memory location
- push cx ;save CX, we'll be using it to loop
- mov cx, 5 ;loop five times, test ports 210h-260h
- chkports:
- push cx
- mov cx, 200h
- add dx, 0Ch
- chkport1:
- in al, dx
- and al, 80h
- cmp al, 0
- je short foundport1
- loop chkport1
- jmp short test2
- foundport1:
- inc sbflag ;first port in set found
- test2:
- pop cx
- cmp [sbflag], 0
- je short nextports ;no tests passed? go to next set
- in al, dx ;small timing delay
- mov al, 0d3h
- out dx, al
- push cx
- mov cx, 1000h
- donothing:
- loop donothing ;large timing delay
- pop cx
- mov dx, [di]
- add dx, 6
- mov al, 1
- out dx, al
- rept 4
- in al, dx ;timing delay
- endm
- mov al, 0
- out dx, al
- mov dx, [di]
- add dx, 0Eh
- push cx
- mov cx, 200h
- chkport2:
- in al, dx
- test al, 80h
- je short foundport2
- loop chkport2
- jmp short noport2
- foundport2:
- inc sbflag ;found second port in series
- noport2:
- pop cx
- cmp [sbflag], 2
- jb nextports ;go to next set of ports
- mov dx, [di]
- add dx, 0Ah
- in al, dx
- cmp al, 0AAh
- jne nextports
- inc sbflag ;found third port in series
- mov ax, 1 ;found SB, return AX=1
- jmp yes_sb
- nextports:
- add word ptr [di], 10h
- mov dx, [di]
- if ($-chkports) lt 128
- loop chkports
- else
- dec cx
- cmp cx, 0
- je @a
- jmp chkports
- @a:
- endif
- mov ax, 0 ;found no SB, return AX=0
- yes_sb:
- pop cx
- pop dx
- ret
- endp
- END
-